
/*!	@brief The View class is used, as the name implied, as a "camera" 
 *  viewing the world. 
 */
 
 View  = function()
{
	/************************************
	/*			Properties				
	/************************************/
	
		this.m_Transform;
		this.m_Projection;
		this.m_Viewport;	/*!< Viewport (Rect) attached to the current View 	*/
		
}

	/*!	@brief Return the world position from specified mouse coordinates	*/
	View.prototype.MouseToWorld	=	function(x, y, z)
	{
		if( this.m_Viewport.IsIn(new Vec4(x, y, 0, 0)))
		{
			var worldPos		=	new Vec4(0.0, 0.0, z, 1.0);
			
			// First, we must transform the 0-width and 0-height to [-1;1]
			
			worldPos.x	=	Maths.IntervalToInterval(0, this.m_Viewport.m_Width, -1, 1,  x - this.m_Viewport.m_LeftBottom.x);
			worldPos.y	=	Maths.IntervalToInterval(0, this.m_Viewport.m_Height, 1, -1, y - this.m_Viewport.m_LeftBottom.y);
			
			// Then, we apply the inverse View and projection matrix to get back the
			// "real" position in world space
			
			worldPos 	=	this.m_Projection.m_Inverse.MultVec4(worldPos); 
			worldPos	=	this.Inverse().MultVec4(worldPos);
			
			return worldPos;
		}
	}

	/*!	@brief Return the Matrix of the current View	*/
	View.prototype.GetViewMatrix	=	function()
	{
		return this.m_Transform.m_WorldMatrix;
	}
	
	View.prototype.SetViewMatrix	=	function()
	{
		console.log(this.m_Transform.m_Position.x);
		var posMatrix		=	Matrix4.Translation(this.m_Transform.m_Position);
		var posInverse		=	Matrix4.TranslationInverse(this.m_Transform.m_Position);
		
		var rotMatrix		=	Quaternion.Euler(this.m_Transform.m_EulerAngles);
		var rotInverse		=	Quaternion.EulerInverse(this.m_Transform.m_EulerAngles);
		
		var scaleMatrix		=	Matrix4.Scale(this.m_Transform.m_Scale);
		var scaleInverse	=	Matrix4.ScaleInverse(this.m_Transform.m_Scale);
		
		this.m_Transform.m_LocalMatrix	=	rotMatrix.MultMatrix(posMatrix).MultMatrix(scaleMatrix);
		this.m_Transform.m_LocalInverse	=	posInverse.MultMatrix(scaleInverse).MultMatrix(rotInverse);

		if(this.m_Father!=undefined)
		{
			this.m_Transform.m_WorldMatrix	=	this.m_Father.m_Transform.m_WorldMatrix.MultMatrix(this.m_Transform.m_LocalMatrix);
			this.m_Transform.m_WorldInverse	=	this.m_Father.m_Transform.m_WorldInverse.MultMatrix(this.m_Transform.m_LocalInverse);
		}
	}
			
	View.prototype.Update	=	function()
	{
		this.SetViewMatrix();
	}
	
	/*!	@brief Return the Inverse Matrix of current View	*/
	View.prototype.Inverse	=	function()
	{
		return this.m_Entity.m_Transform.m_PositionInverse;
	}

	View.prototype.LookAt=	function()
	{

	}

	View.prototype.Move	=	function(x, y)
	{
		if(Mouse.Buttons[0]==MouseState.Pressed)
		{
			this.m_Entity.m_Transform.SetPosition(this.m_Entity.m_Transform.GetPosition().x + x, this.m_Entity.m_Transform.GetPosition().y - y, 0);
			this.m_ViewMatrix					=	this.m_Entity.m_Transform.m_PositionMatrix;
		}
	}

	View.prototype.RayFromScreen	=	function(x,y)
	{
		return (new Ray
						( 	
							this.MouseToWorld(x,y,0),
							this.MouseToWorld(x,y,1), 10
						)
				);
	}

	/**********************************************
	/*		Static Properties
	/**********************************************/

		View.Current;	/*!< Store the view currently rendering the scene */
		View.Views	=	new Array();	/*!< Store all Initialized views	*/
		
	/**********************************************
	/*		Static Methods
	/**********************************************/

		/*!	@brief Instantiate a view, Meaning it'll create a new Entity at "position",
		 * 	initialize it's viewPort and projection	*/
		View.Instantiate	=	function( transformation, viewPort, projection)
		{
			var view = new View();
			
			view.m_Viewport		=	viewPort;
			view.m_Projection	=	projection;
			view.m_Transform = transformation;
			
			
			View.Views.push(view);
			return view;
		}
		
		/*!	@brief Return the inverse Matrix of the default view	*/
		View.Inverse	=	function()
		{
			return View.Default.m_Entity.m_Transform.m_PositionInverse;
		}

		/*!	@brief Return the Projection of the default view		*/
		View.Projection	=	function()
		{
			return View.Default.m_Projection;
		}



